/**********************************************************************/
/* Programa: COMPRESOR 
Este programa es el encargado del manejo de TDA - lista del compresor
Integrantes        : Catalina Windmuller, Ayelén Tamiozzo y Francisco Soler               
Fecha              : 17 de abril de 2011                                 
Versión            : 01                                                     
Nombre del archivo : lista.c */

/**********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "lista.h"
/**********************************************************************/

//char *strdup(const char*);

/**********************************************************************/
/* crear_lista: ver lista.h */ 
bool crear_lista (tlista *lista){
	*lista = NULL;
	return true;
}

/**********************************************************************/
/* lista_vacia: ver lista.h */
bool lista_vacia (tlista lista){
    return (lista==NULL);
}
    
/**********************************************************************/
/* insertar_lista_primero: ver lista.h */
bool insertar_lista_primero (tlista *lista, tdatol dato){
	void *aux = malloc (sizeof (struct tnodol));
	if (aux == NULL)
		return false;
	tlista nodo_nuevo = (tlista) aux;
	nodo_nuevo->dato = dato;
	nodo_nuevo->siguiente = *lista;
	*lista = nodo_nuevo;
	return true;
}

/**********************************************************************/
/* borrar_lista_primero: se elimina el primer nodo de la lista y se devuel-
 * ve el valor almacenado en el mismo */
bool borrar_lista_primero (tlista *lista, tdatol *dato){
	if (lista_vacia (*lista))
		return false;
	
	*dato=(*lista)->dato;	
	tlista aux = *lista;
	*lista = (*lista) ->siguiente;
	free (aux);
	return true;
}

/**********************************************************************/
/* listar_primero: devuelve el dato señalado por el primer nodo, si la 
 * lista no es vacía */
bool listar_primero (const tlista *lista, tdatol *dato){
	if (!lista_vacia(*lista)){
		*dato = (*lista)->dato;
		return true;}
	return false;
}

/**********************************************************************/
/* destruir_lista: ver lista.h */
bool destruir_lista (tlista *lista, destruir_dato_lista destruir){
   struct tnodol *actual,*sucesor;

   actual = *lista;
   while (actual != NULL) {
      sucesor = actual->siguiente;
	  destruir(actual->dato);
      free(actual);
      actual = sucesor;
   }
   *lista = NULL;
   return true;
}
/********************************************************************/
/* crear_lista_iter: ver lista.h */
bool crear_lista_iter(tlista *lista, tlista_iter *iter){
	iter->actual = *lista;
	iter->anterior=NULL;
	return true;}
	
/********************************************************************/
/* lista_iter_final: ver lista.h */
bool lista_iter_final (tlista_iter* iter){
	return (iter->actual == NULL);
}

/********************************************************************/
/* avanzar_lista_iter: ver lista.h */
bool avanzar_lista_iter (tlista_iter* iter){
	if (lista_iter_final(iter))
		return false;
	iter->anterior = iter->actual;
	iter->actual = iter->actual->siguiente;
	return true;
}

/*********************************************************************/
/* ver_lista_actual: ver lista.h */
bool ver_lista_actual (tlista_iter* iter, tdatol* dato){
	if (lista_iter_final (iter))
		return false;
	*dato = iter->actual->dato;
	return true;
}

/********************************************************************/
/* redireccionar_pincipio: redirecciona el puntero que señala el 
 * principio de la lista */
bool redireccionar_principio (tlista* lista, tlista_iter* iter){
	if (lista_vacia(iter->anterior)){
			(*lista)= iter->actual;}
	else {
			iter->anterior->siguiente = iter->actual;}
	return true;
}
               
/********************************************************************/
/* insertar_lista: ver lista.h */
bool insertar_lista (tlista *lista, tlista_iter * iter, tdatol dato){
	if (insertar_lista_primero(&iter->actual, dato)){
		return (redireccionar_principio (lista, iter));}
	return false;
}
		
/********************************************************************/
/* borrar_lista: ver lista.h */
bool borrar_lista (tlista *lista, tlista_iter *iter, tdatol *dato){
	if (lista_iter_final(iter))
		return false;
	if (!borrar_lista_primero(&iter->actual,dato))
		return false;
	return (redireccionar_principio (lista, iter));
}
/********************************************************************/
